#include "GomokuBoard.h"

GomokuBoard::GomokuBoard(void)
{
	for(int a = 0; a < boardHeight*boardWidth; a++)
	{
		data[a] = 0;
	}
}

GomokuBoard::GomokuBoard(Board data)
{
	for(int x = 0; x < boardWidth; x++)
	{
		for(int y = 0; y < boardHeight; y++)
		{
			Set(x,y,data[x][y]);
		}
	}
}

GomokuBoard::GomokuBoard(std::istream &stream)
{
	Parse(stream);
}

GomokuBoard::GomokuBoard(GomokuBoard &_parent, Square _move, int _playerNum)
{
	for(int x = 0; x < boardWidth; x++)
	{
		for(int y = 0; y < boardHeight; y++)
		{
			if(x == _move.x && y == _move.y && _parent.Get(x,y) == 0)
				Set(x,y,_playerNum);
			else
				Set(x,y,_parent.Get(x,y));
		}
	}
}

GomokuBoard::~GomokuBoard(void)
{
}

int GomokuBoard::Get(int _x, int _y)
{
	if(_x >= 0 && _y >= 0 && _x < boardWidth && _y < boardHeight)
		return data[_x*boardHeight + _y];
	return -1;
}

bool GomokuBoard::InBounds(int x, int y)
{
	if(x >= 0 && y >= 0 && x < boardWidth && y < boardHeight)
		return true;
	return false;
}

bool GomokuBoard::CheckForWin(int _player)
{
	// Check Horizontal
	for(int a = 0; a < 19; a++)
	{
		for(int b = 0; b < 14; b++)
		{
			int t_numberInRow = 0;
			for(int c = 0; c < 5; c++)
			{
				if(Get(b + c, a) == _player) t_numberInRow++;
			}
			if(t_numberInRow == 5) return true;
		}
	}

	// Check Vertical
	for(int a = 0; a < 19; a++)
	{
		for(int b = 0; b < 14; b++)
		{
			int t_numberInColumn = 0;
			for(int c = 0; c < 5; c++)
			{
				if(Get(a, b + c) == _player) t_numberInColumn++;
			}
			if(t_numberInColumn == 5) return true;
		}
	}

	// Check Diagonal
		// Top -> Bottom Diagonals
	for(int a = 0; a < 15; a++)
	{
		for(int b = 0; b < 15; b++)
		{
			int t_numberInDiagonal = 0;
			for(int c = 0; c < 5; c++)
			{
				if(Get(a + c, b + c) == _player) t_numberInDiagonal++;
			}
			if(t_numberInDiagonal == 5) return true;
		}
	}
	// Bottom -> Top Diagonals
	for(int a = 0; a < 15; a++)
	{
		for(int b = 18; b > 3; b--)
		{
			int t_numberInDiagonal = 0;
			for(int c = 0; c < 5; c++)
			{
				if(Get(a + c, b - c) == _player) t_numberInDiagonal++;
			}
			if(t_numberInDiagonal == 5) return true;
		}
	}
	return false;
}

std::vector<Square> GomokuBoard::PossibleMoves(int _playerNum)
{
	std::vector<Square> t_moves;
	for(int x = 0;x < boardWidth;x++) {
		for(int y = 0;y < boardHeight;y++) {
			bool neigborFound = false;
			if(Get(x,y) == 0) {
				for(int dx = -1; dx <= 1; dx++) {
					for(int dy = -1; dy <= 1; dy++) {
						if(Get(x + dx, y + dy) > 0) {
							t_moves.push_back(*(new Square(x,y)));
							neigborFound = true;
							break;
						}
					}
					if(neigborFound)
						break;
				}
			}

		}
	}
	return t_moves;
}

void GomokuBoard::Set(int _x, int _y, int _value)
{
	data[_x*boardWidth + _y] = _value;
}

void GomokuBoard::GetBoard(Board &board)
{
	for(int a = 0; a < 19; a++) for(int b = 0; b < 19; b++) board[a][b] = Get(a, b);
}

void GomokuBoard::Write(std::ostream &stream)
{
	for(int a = 0; a < 19; a++) for(int b = 0; b < 19; b++) stream << Get(a, b) << "\n";
	stream << "\n";
}

void GomokuBoard::Parse(std::istream &stream)
{
	std::stringbuf t_buffer;

	stream.get(t_buffer);

	std::stringstream t_stream(t_buffer.str());

	for(int a = 0; a < 19; a++) for(int b = 0; b < 19; b++)
	{
		char t_number[20];
		t_stream.get(t_number, 20);
		Set(a, b, atoi(t_number));
		t_stream.ignore();
	}
}